/*     */ package com.zimbra.cs.account;
/*     */ 
/*     */ import com.zimbra.common.mime.shim.JavaMailInternetAddress;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import gnu.inet.encoding.IDNA;
/*     */ import gnu.inet.encoding.IDNAException;
/*     */ import java.io.PrintStream;
/*     */ import java.io.UnsupportedEncodingException;
/*     */ import java.lang.reflect.Field;
/*     */ import java.lang.reflect.InvocationTargetException;
/*     */ import java.lang.reflect.Method;
/*     */ import java.util.StringTokenizer;
/*     */ import java.util.regex.Matcher;
/*     */ import java.util.regex.Pattern;
/*     */ import javax.mail.internet.AddressException;
/*     */ import javax.mail.internet.InternetAddress;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class IDNUtil
/*     */ {
/*     */   public static final String ACE_PREFIX = "xn--";
/*     */   
/*     */   private static abstract class ZimbraIDN
/*     */   {
/*     */     private static final boolean sAllowUnassigned = true;
/*     */     private static final boolean sUseSTD3ASCIIRules = false;
/*  50 */     private static final ZimbraIDN INSTANCE = ;
/*     */     
/*     */     private static ZimbraIDN getInstance()
/*     */     {
/*  54 */       ZimbraIDN instance = IDNUtil.JavaIDN.getInstance(true, false);
/*  55 */       if (instance == null) {
/*  56 */         instance = new IDNUtil.GnuIDN(true, false, null);
/*     */       }
/*  58 */       return instance;
/*     */     }
/*     */     
/*     */     abstract String toASCII(String paramString) throws ServiceException;
/*     */     
/*     */     abstract String toUnicode(String paramString) throws ServiceException;
/*     */     
/*     */     private static String convertToASCII(String input) {
/*  66 */       try { return INSTANCE.toASCII(input);
/*     */       }
/*     */       catch (ServiceException e) {
/*  69 */         ZimbraLog.account.info("domain [" + input + "] cannot be converted to ASCII", e); }
/*  70 */       return input;
/*     */     }
/*     */     
/*     */     private static String convertToUnicode(String input)
/*     */     {
/*     */       try {
/*  76 */         return INSTANCE.toUnicode(input);
/*     */       }
/*     */       catch (ServiceException e) {
/*  79 */         ZimbraLog.account.info("domain [" + input + "] cannot be converted to Unicode", e); }
/*  80 */       return input;
/*     */     }
/*     */   }
/*     */   
/*     */   private static class JavaIDN
/*     */     extends IDNUtil.ZimbraIDN
/*     */   {
/*     */     private static final String SEGMENT_DELIM = ".";
/*     */     private int mFlags;
/*     */     private Method mMethodToASCII;
/*     */     private Method mMethodToUnicode;
/*     */     private int ALLOW_UNASSIGNED;
/*     */     private int USE_STD3_ASCII_RULES;
/*     */     
/*     */     private static JavaIDN getInstance(boolean allowUnassigned, boolean useSTD3ASCIIRules)
/*     */     {
/*     */       try
/*     */       {
/*  98 */         return new JavaIDN(allowUnassigned, useSTD3ASCIIRules);
/*     */       }
/*     */       catch (ServiceException e) {}
/* 101 */       return null;
/*     */     }
/*     */     
/*     */     private JavaIDN(boolean allowUnassigned, boolean useSTD3ASCIIRules)
/*     */       throws ServiceException
/*     */     {
/* 107 */       super();
/*     */       try {
/* 109 */         Class cls = Class.forName("java.net.IDN");
/* 110 */         this.mMethodToASCII = cls.getMethod("toASCII", new Class[] { String.class, Integer.TYPE });
/* 111 */         this.mMethodToUnicode = cls.getMethod("toUnicode", new Class[] { String.class, Integer.TYPE });
/* 112 */         Field fieldAllowUnassigned = cls.getField("ALLOW_UNASSIGNED");
/* 113 */         Field fieldUseSTD3ASCIIRules = cls.getField("USE_STD3_ASCII_RULES");
/*     */         
/*     */ 
/* 116 */         if ((this.mMethodToASCII == null) || (this.mMethodToUnicode == null) || (fieldAllowUnassigned == null) || (fieldUseSTD3ASCIIRules == null))
/*     */         {
/* 118 */           throw ServiceException.FAILURE("JavaIDN not supported", null);
/*     */         }
/* 120 */         this.ALLOW_UNASSIGNED = fieldAllowUnassigned.getInt(null);
/* 121 */         this.USE_STD3_ASCII_RULES = fieldUseSTD3ASCIIRules.getInt(null);
/*     */         
/* 123 */         this.mFlags = 0;
/* 124 */         if (allowUnassigned) {
/* 125 */           this.mFlags |= this.ALLOW_UNASSIGNED;
/*     */         }
/* 127 */         if (useSTD3ASCIIRules) {
/* 128 */           this.mFlags |= this.USE_STD3_ASCII_RULES;
/*     */         }
/*     */         
/* 131 */         return;
/*     */       }
/*     */       catch (ClassNotFoundException e) {}catch (NoSuchMethodException e) {}catch (NoSuchFieldException e) {}catch (IllegalAccessException e) {}
/*     */       
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 140 */       throw ServiceException.FAILURE("JavaIDN not supported", null);
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     String toASCII(String input)
/*     */       throws ServiceException
/*     */     {
/*     */       try
/*     */       {
/* 163 */         StringBuffer sb = new StringBuffer();
/* 164 */         StringTokenizer tokenizer = new StringTokenizer(input, ".", true);
/* 165 */         while (tokenizer.hasMoreTokens()) {
/* 166 */           String token = tokenizer.nextToken();
/* 167 */           if (!".".equals(token)) {
/* 168 */             token = (String)this.mMethodToASCII.invoke(null, new Object[] { token, Integer.valueOf(this.mFlags) });
/*     */           }
/* 170 */           sb.append(token);
/*     */         }
/* 172 */         return sb.toString();
/*     */       } catch (IllegalAccessException e) {
/* 174 */         throw ServiceException.FAILURE("cannot convert to ASCII", e);
/*     */       } catch (IllegalArgumentException e) {
/* 176 */         throw ServiceException.FAILURE("cannot convert to ASCII", e);
/*     */       } catch (InvocationTargetException e) {
/* 178 */         throw ServiceException.FAILURE("cannot convert to ASCII", e);
/*     */       }
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */     String toUnicode(String input)
/*     */       throws ServiceException
/*     */     {
/*     */       try
/*     */       {
/* 190 */         StringBuffer sb = new StringBuffer();
/* 191 */         StringTokenizer tokenizer = new StringTokenizer(input, ".", true);
/* 192 */         while (tokenizer.hasMoreTokens()) {
/* 193 */           String token = tokenizer.nextToken();
/* 194 */           if (!".".equals(token)) {
/* 195 */             token = (String)this.mMethodToUnicode.invoke(null, new Object[] { token, Integer.valueOf(this.mFlags) });
/*     */           }
/* 197 */           sb.append(token);
/*     */         }
/* 199 */         return sb.toString();
/*     */       } catch (IllegalAccessException e) {
/* 201 */         throw ServiceException.FAILURE("cannot convert to Unicode", e);
/*     */       } catch (IllegalArgumentException e) {
/* 203 */         throw ServiceException.FAILURE("cannot convert to Unicode", e);
/*     */       } catch (InvocationTargetException e) {
/* 205 */         throw ServiceException.FAILURE("cannot convert to Unicode", e);
/*     */       }
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static class GnuIDN
/*     */     extends IDNUtil.ZimbraIDN
/*     */   {
/*     */     private boolean mAllowUnassigned;
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     private boolean mUseSTD3ASCIIRules;
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     private GnuIDN(boolean allowUnassigned, boolean useSTD3ASCIIRules)
/*     */     {
/* 242 */       super();
/* 243 */       this.mAllowUnassigned = allowUnassigned;
/* 244 */       this.mUseSTD3ASCIIRules = useSTD3ASCIIRules;
/*     */     }
/*     */     
/*     */     String toASCII(String input) throws ServiceException {
/*     */       try {
/* 249 */         StringBuffer o = new StringBuffer();
/* 250 */         StringBuffer h = new StringBuffer();
/*     */         
/* 252 */         for (int i = 0; i < input.length(); i++) {
/* 253 */           char c = input.charAt(i);
/* 254 */           if ((c == '.') || (c == '。') || (c == 65294) || (c == 65377)) {
/* 255 */             o.append(IDNA.toASCII(h.toString(), this.mAllowUnassigned, this.mUseSTD3ASCIIRules));
/* 256 */             o.append('.');
/* 257 */             h = new StringBuffer();
/*     */           } else {
/* 259 */             h.append(c);
/*     */           }
/*     */         }
/* 262 */         o.append(IDNA.toASCII(h.toString(), this.mAllowUnassigned, this.mUseSTD3ASCIIRules));
/* 263 */         return o.toString();
/*     */       } catch (IDNAException e) {
/* 265 */         throw ServiceException.FAILURE("cannot convert to ASCII", e);
/*     */       }
/*     */     }
/*     */     
/*     */     String toUnicode(String input) {
/* 270 */       StringBuffer o = new StringBuffer();
/* 271 */       StringBuffer h = new StringBuffer();
/*     */       
/* 273 */       for (int i = 0; i < input.length(); i++) {
/* 274 */         char c = input.charAt(i);
/* 275 */         if ((c == '.') || (c == '。') || (c == 65294) || (c == 65377)) {
/* 276 */           o.append(IDNA.toUnicode(h.toString(), this.mAllowUnassigned, this.mUseSTD3ASCIIRules));
/* 277 */           o.append(c);
/* 278 */           h = new StringBuffer();
/*     */         } else {
/* 280 */           h.append(c);
/*     */         }
/*     */       }
/* 283 */       o.append(IDNA.toUnicode(h.toString(), this.mAllowUnassigned, this.mUseSTD3ASCIIRules));
/* 284 */       return o.toString();
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   public static String toAsciiDomainName(String name)
/*     */   {
/* 293 */     return ZimbraIDN.convertToASCII(name);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   public static String toUnicodeDomainName(String name)
/*     */   {
/* 300 */     return ZimbraIDN.convertToUnicode(name);
/*     */   }
/*     */   
/*     */   public static String toAsciiEmail(String emailAddress) throws ServiceException {
/* 304 */     String[] parts = emailAddress.split("@");
/*     */     
/* 306 */     if (parts.length != 2) {
/* 307 */       throw ServiceException.INVALID_REQUEST("must be valid email address: " + emailAddress, null);
/*     */     }
/* 309 */     String localPart = parts[0];
/* 310 */     String domain = parts[1];
/* 311 */     emailAddress = localPart + "@" + toAsciiDomainName(domain);
/* 312 */     return emailAddress;
/*     */   }
/*     */   
/*     */   public static String toUnicodeEmail(String emailAddress) throws ServiceException {
/* 316 */     String[] parts = emailAddress.split("@");
/*     */     
/* 318 */     if (parts.length != 2) {
/* 319 */       throw ServiceException.INVALID_REQUEST("must be valid email address: " + emailAddress, null);
/*     */     }
/* 321 */     String localPart = parts[0];
/* 322 */     String domain = parts[1];
/* 323 */     emailAddress = localPart + "@" + toUnicodeDomainName(domain);
/* 324 */     return emailAddress;
/*     */   }
/*     */   
/*     */   public static String toAscii(String name, AttributeManager.IDNType idnType) {
/* 328 */     switch (idnType) {
/*     */     case email: 
/* 330 */       return toAscii(name);
/*     */     case emailp: 
/* 332 */       return toAsciiWithPersonalPart(name);
/*     */     case cs_emailp: 
/* 334 */       String[] names = name.split(",");
/* 335 */       StringBuilder out = new StringBuilder();
/* 336 */       boolean first = true;
/* 337 */       for (String n : names) {
/* 338 */         if (first) {
/* 339 */           first = false;
/*     */         } else
/* 341 */           out.append(", ");
/* 342 */         out.append(toAsciiWithPersonalPart(n.trim()));
/*     */       }
/* 344 */       return out.toString();
/*     */     }
/* 346 */     return name;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 405 */   private static Pattern S_DOMAIN = Pattern.compile("(.+)(@)([^>]*)(.*)");
/*     */   
/*     */   private static String toAsciiWithPersonalPart(String name)
/*     */   {
/* 409 */     String asciiName = name;
/*     */     
/*     */ 
/* 412 */     Matcher m = S_DOMAIN.matcher(name);
/* 413 */     if ((m.matches()) && (m.groupCount() == 4))
/*     */     {
/* 415 */       String domain = m.group(3);
/* 416 */       String asciiDomain = toAsciiDomainName(domain);
/*     */       
/*     */ 
/* 419 */       asciiName = m.group(1) + m.group(2) + asciiDomain + m.group(4);
/*     */     }
/*     */     try {
/* 422 */       InternetAddress ia = new JavaMailInternetAddress(asciiName);
/*     */       
/* 424 */       String personal = ia.getPersonal();
/* 425 */       if (personal != null) {
/* 426 */         ia = new JavaMailInternetAddress(ia.getAddress(), personal, "utf-8");
/*     */       }
/*     */       
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 438 */       return ia.toString();
/*     */     } catch (UnsupportedEncodingException e) {
/* 440 */       ZimbraLog.account.info("cannot convert to ascii, returning original addr: [" + name + "]", e);
/*     */     } catch (AddressException e) {
/* 442 */       ZimbraLog.account.info("cannot convert to ascii, returning original addr: [" + name + "]", e);
/*     */     }
/*     */     
/* 445 */     return name;
/*     */   }
/*     */   
/*     */   public static String toAscii(String name) {
/* 449 */     if (name == null) {
/* 450 */       return null;
/*     */     }
/*     */     try {
/* 453 */       if (name.contains("@")) {
/* 454 */         return toAsciiEmail(name);
/*     */       }
/* 456 */       return toAsciiDomainName(name);
/*     */     } catch (ServiceException e) {}
/* 458 */     return name;
/*     */   }
/*     */   
/*     */ 
/*     */   public static String toUnicode(String name, AttributeManager.IDNType idnType)
/*     */   {
/* 464 */     switch (idnType) {
/*     */     case email: 
/* 466 */       return toUnicode(name);
/*     */     case emailp: 
/* 468 */       return toUnicodeWithPersonalPart(name);
/*     */     case cs_emailp: 
/* 470 */       String[] names = name.split(",");
/* 471 */       StringBuilder out = new StringBuilder();
/* 472 */       boolean first = true;
/* 473 */       for (String n : names) {
/* 474 */         if (first) {
/* 475 */           first = false;
/*     */         } else
/* 477 */           out.append(", ");
/* 478 */         out.append(toUnicodeWithPersonalPart(n.trim()));
/*     */       }
/* 480 */       return out.toString();
/*     */     }
/* 482 */     return name;
/*     */   }
/*     */   
/*     */   private static String toUnicodeWithPersonalPart(String name)
/*     */   {
/*     */     try {
/* 488 */       InternetAddress ia = new JavaMailInternetAddress(name, true);
/*     */       
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 496 */       String addr = ia.getAddress();
/* 497 */       String unicodeAddr = toUnicode(addr);
/*     */       try {
/* 499 */         ia = new JavaMailInternetAddress(unicodeAddr, ia.getPersonal(), "utf-8");
/*     */         
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 507 */         return ia.toUnicodeString();
/*     */       } catch (UnsupportedEncodingException e) {
/* 509 */         ZimbraLog.account.info("cannot convert to unicode, returning original addr: [" + name + "]", e);
/*     */       }
/*     */       
/*     */ 
/*     */ 
/*     */ 
/* 515 */       return name;
/*     */     }
/*     */     catch (AddressException e)
/*     */     {
/* 512 */       ZimbraLog.account.info("cannot convert to unicode, returning original addr: [" + name + "]", e);
/*     */     }
/*     */   }
/*     */   
/*     */ 
/*     */   public static String toUnicode(String name)
/*     */   {
/* 519 */     if (name == null) {
/* 520 */       return null;
/*     */     }
/*     */     try {
/* 523 */       if (name.contains("@")) {
/* 524 */         return toUnicodeEmail(name);
/*     */       }
/* 526 */       return toUnicodeDomainName(name);
/*     */     } catch (ServiceException e) {}
/* 528 */     return name;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */   private static void regexTest(String input)
/*     */   {
/* 536 */     System.out.print(input + " ==> ");
/* 537 */     Matcher m = S_DOMAIN.matcher(input);
/* 538 */     if (m.matches()) {
/* 539 */       int groupsMatched = m.groupCount();
/* 540 */       for (int i = 1; i <= groupsMatched; i++)
/* 541 */         System.out.print("[" + i + " " + m.group(i) + "]");
/* 542 */       System.out.println();
/*     */     } else {
/* 544 */       System.out.println("don't match");
/*     */     }
/*     */   }
/*     */   
/*     */   public static void main(String[] args) {
/* 549 */     regexTest("test.com");
/* 550 */     regexTest("@test.com");
/* 551 */     regexTest("@test.com>aaa");
/* 552 */     regexTest("user@test.com>aaa");
/* 553 */     regexTest("foo bar <user@test.com>");
/* 554 */     regexTest("foo bar <user@test.com");
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/account/IDNUtil.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */